#include "main.h"
#include <iostream>
#include <fstream>
//#include <stdio.h>
#include "bitstream.h"
#include "huffmancodec.h"
#include "main.h"

#define T ui8
/*
void test() {
    FILE *file = fopen("in.pdf","r");
//    ifstream f;
//    f.open("in.pdf",ios_base::in|ios_base::binary);
    TIMER_CODE( TStopwatch watch; )
    for(ui64 i=0; i<1<<8; i++) {
        ui64 c[512];

        //char *mem="qwertyuoip";
        TIMER_CODE(watch.ResetTsc();)
        //f.readsome((char*)&c,8);
        fread((char*)&c,8,512,file);
        //memcpy((char*)&c,mem,8);
        TIMER_CODE(watch.Count();)
        //printf("%c\n",c);
    }
    TIMER_CODE(cout <<"Watch average: " << watch.GetAverageTsc() << endl;)
//    f.close();
    //printf("average tsc: %d\n",watch.GetAverageTsc());
    fclose(file);
}
*/
/*
int ios_main (int argc,char* argv[]) {
    if ( argc == 4 ) {
        ifstream in;
        ofstream out;
        if (!strcmp("-c", argv[1]) || !strcmp("--code", argv[1])) {
            try {
                in.open(argv[2], ios::in | ios::binary);
                out.open(argv[3], ios::out | ios::binary);
                TStopwatch stopwatch("Coding.");
                HuffmanFileCompress<T>(&in,&out);
                stopwatch.Print();
            } catch(TException &e) {
                cout<<e.what()<<endl;
            } catch (...) {
                cout<<"Coding error."<<endl;
            }
            if (in.is_open()) in.close();
            if (out.is_open()) out.close();
        } else if (!strcmp("-d", argv[1]) || !strcmp("--decode", argv[1])) {
            try {
                in.open(argv[2], ios::in | ios::binary);
                out.open(argv[3], ios::out | ios::binary);
                TStopwatch stopwatch("Decoding.");
                HuffmanFileDecompress<T>(&in,&out);
                stopwatch.Print();
            } catch(TException &e) {
                cout<<e.what()<<endl;
            } catch (...) {
                cout<<"Decoding error."<<endl;
            }
            if (in.is_open()) in.close();
            if (out.is_open()) out.close();
        } else {
            puts("\nThis demo program provides coding of files by static Huffman's algorithm.");
            puts("Authors: Kuralenok I.E., Zheleznov A.V.. 2012.\n");
            puts("USAGE: [operation] [file_input] [file_output]\n");
            puts("Operations: ");
            puts("		-c, --code          Code file_input into file_output.");
            puts("		-d, --decode		Decode file_input into file_output.");
        }
    }
    //DEBUG_CODE ( IdentityTestStdio("in.pdf","out.pdf");    )
    return 0;
}
*/

int main(int argc,char* argv[]) {
    if ( argc == 4 ) {
        FILE* in;
        FILE* out;
        if (!strcmp("-c", argv[1]) || !strcmp("--code", argv[1])) {
            try {
                in = fopen(argv[2], "r");
                out = fopen(argv[3], "w");
                TStopwatch stopwatch("Coding.");
                HuffmanFileCompress<T>(in,out);
                stopwatch.Print();
            } catch(TException &e) {
                cout<<e.what()<<endl;
            } catch(string &e) {
                cout<<e<<endl;
            } catch (...) {
                cout<<"Coding error."<<endl;
            }
            fclose(in);
            fclose(out);
        } else if (!strcmp("-d", argv[1]) || !strcmp("--decode", argv[1])) {
            try {
                in = fopen(argv[2], "r");
                out = fopen(argv[3], "w");
//                HuffmanOldDecoding<T>(in, out);
//                HuffmanTestDecoding<T>(in, out);
				TStopwatch stopwatch("Decoding.");
				HuffmanFileDecompress<T>(in,out);
				stopwatch.Print();
			} catch(TException &e) {
				cout<<e.what()<<endl;
			} catch(string &e) {
				cout<<"Decoding error: "<<e<<endl;
			} catch (...) {
				cout<<"Decoding error."<<endl;
			}
            fclose(in);
            fclose(out);
        } else {
            puts("\nThis demo program provides coding of files by static Huffman's algorithm.");
            puts("Authors: Kuralenok I.E., Zheleznov A.V.. 2012.\n");
            puts("USAGE: [operation] [file_input] [file_output]\n");
            puts("Operations: ");
			puts("		-c, --code          Code file_input into file_output.");
            puts("		-d, --decode		Decode file_input into file_output.");
        }
    }
    DEBUG_CODE	(IdentityTestStdio("in.txt","out.txt");)
    return 0;    
}
//node: 11 : symb : 41 : 00101001 : code : 10001100111000 : 14
